#include "httpserver.h"
namespace Http
{
	HttpServer::HttpServer()
	{
		// 先注册一下所有code
		HttpTypeManger::setAllCode();
		m_thread_running = false;
	}

	HttpServer::HttpServer(int port):m_port(port)
	{
		// 先注册一下所有code
		HttpTypeManger::setAllCode();
		m_thread_running = false;
	}

	HttpServer::~HttpServer()
	{
		if (m_thread_running)
		{
			this->stop();
		}
		
	}

	void HttpServer::httpCallBack(mg_connection *connection, int event_type, void *event_data)
	{
		HttpServer *p_this = (HttpServer *)connection->mgr->mg_this;
		if (p_this == nullptr)
		{
			return;
		}

		// 区分http和websocket
		if (event_type == MG_EV_HTTP_REQUEST)
		{
			http_message *http_req = (http_message *)event_data;
			/*std::string req_str = std::string(http_req->message.p, http_req->message.len);
			Log::printDebug("got request: "+ req_str);*/

			std::string path = std::string(http_req->uri.p, http_req->uri.len);
			//Log::printDebug("got path: " + path);
			if (p_this->p_server_reply != nullptr)
			{
				HttpServerReply reply(connection, http_req);
				p_this->p_server_reply(reply, path,(char *)http_req->body.p,http_req->body.len);
			}
		}
	}

	// 监听
	bool HttpServer::listen(int port)
	{
		if (port == -1 && m_port == -1)
		{
			return false;
		}

		if (port != -1)
		{
			m_port = port;
		}

		if (m_thread_running)
		{
			Log::printError("StreamManger::start 线程已经初始化切莫再次初始化");
			return false;
		}

		m_thread_running = true;

		if (p_thread == nullptr)
		{
			auto func = std::bind(&HttpServer::getAllNetMessage, this);
			p_thread = new std::thread(func);
		}
	

		return true;
	}

	void HttpServer::getAllNetMessage()
	{
		while (m_thread_running)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(500));
			Log::printInfo("系统即将监听 port: " + std::to_string(m_port));
			mg_mgr_init(&m_mgr, NULL);
			// 注册一下本地的this指针
			m_mgr.mg_this = this;
			mg_connection *connection = mg_bind(&m_mgr, std::to_string(m_port).data(), HttpServer::httpCallBack);
			if (connection == NULL)
			{
				Log::printError(" HttpServer::getAllNetMessage mg_connection *connection绑定失败 端口:"+std::to_string(this->m_port));
				continue;
			}
				
			// for both http and websocket
			mg_set_protocol_http_websocket(connection);

			Log::printInfo("监听成功 port: " + std::to_string(m_port));
			// loop
			while (m_thread_running)
				mg_mgr_poll(&m_mgr, 500); // ms
		}
	}

	// 停止
	bool HttpServer::stop()
	{
		Log::printInfo("HttpServer 连接即将退出 port: " + std::to_string(m_port));
		m_thread_running = false;
		if (p_thread != nullptr)
		{
			p_thread->join();
			delete p_thread;
			p_thread = nullptr;
		}
		mg_mgr_free(&m_mgr);
		Log::printInfo("HttpServer 连接退出:成功 port: " + std::to_string(m_port));
		return true;
	}

	void HttpServer::resigterReplyCallBack(http_server_reply reply)
	{
		p_server_reply = reply;
	}


	HttpServerReply::HttpServerReply(mg_connection *connection, http_message *http_req)
	{
		p_connection = connection;
		p_http_req = http_req;
	}

	HttpServerReply::~HttpServerReply()
	{

	}

	bool HttpServerReply::end(HTTPSTATECODE state_code, char *data, size_t len)
	{
		if (this->p_connection == nullptr || this->p_http_req == nullptr)
		{
			Log::printError("HttpServerReply::end 连接为空，或回执为空不处理请求");
			return false;
		}

		std::string strcode;
		if (!HttpTypeManger::getStateString(state_code, strcode))
		{
			Log::printError("HttpServerReply::end 未获取到需要回执的code号 code:"+std::to_string(state_code));
			return false;
		}

		std::string replay_head = "HTTP/1.1 " + strcode + "\r\n"
			+ "Transfer-Encoding:chunked\r\n"
			//+ "Content-Length:" + std::to_string(len)+"\r\n"
			+ "\r\n"; 
		// 必须先发送header, 暂时还不能用HTTP/2.0
		mg_printf(this->p_connection, "%s", replay_head.data());
		// 以json形式返回
		mg_send_http_chunk(this->p_connection, data,len);
		// 发送空白字符快，结束当前响应
		mg_send_http_chunk(this->p_connection, "", 0);

		return true;
	}

	bool HttpServerReply::sendM3U8(HTTPSTATECODE state_code, char* data, size_t len)
	{
		if (this->p_connection == nullptr || this->p_http_req == nullptr)
		{
			Log::printError("HttpServerReply::end 连接为空，或回执为空不处理请求");
			return false;
		}

		std::string strcode;
		if (!HttpTypeManger::getStateString(state_code, strcode))
		{
			Log::printError("HttpServerReply::end 未获取到需要回执的code号 code:" + std::to_string(state_code));
			return false;
		}

		std::string replay_head = "HTTP/1.1 " + strcode + "\r\n"
			+ "Content-Type: application/vnd.apple.mpegurl\r\n"
			+ "Connection: keep-alive\r\n"
			+ "Access-Control-Allow-Origin: * \r\n"
			+ "Cache-control: no-cache\r\n"
			+ "Content-Length:" + std::to_string(len)+"\r\n"
			+ "\r\n"
			+ data;

		// 必须先发送header, 暂时还不能用HTTP/2.0
		mg_send(this->p_connection,  (const void* )replay_head.data(), replay_head.size());
		

		return true;
	}

	bool HttpServerReply::sendTS(HTTPSTATECODE state_code, char* data, size_t len)
	{
		if (this->p_connection == nullptr || this->p_http_req == nullptr)
		{
			Log::printError("HttpServerReply::end 连接为空，或回执为空不处理请求");
			return false;
		}

		std::string strcode;
		if (!HttpTypeManger::getStateString(state_code, strcode))
		{
			Log::printError("HttpServerReply::end 未获取到需要回执的code号 code:" + std::to_string(state_code));
			return false;
		}

		std::string replay_head = "HTTP/1.1 " + strcode + "\r\n"
			+ "Content-Type: video/mp2t\r\n"
			+ "Connection: keep-alive\r\n"
			+ "Access-Control-Allow-Origin: * \r\n"
			+ "Cache-control: no-cache\r\n"
			+ "Content-Length:" + std::to_string(len) + "\r\n"
			+ "\r\n";

		// 必须先发送header, 暂时还不能用HTTP/2.0 xianfa head
		mg_send(this->p_connection, (const void*)replay_head.data(), replay_head.size());
		mg_send(this->p_connection, (const void*)data, len);

		return true;
	}


	HttpServerReply &HttpServerReply::operator = (const HttpServerReply &replay)
	{
		p_connection = replay.p_connection;
		p_http_req = replay.p_http_req;
		return *this;
	}

}